import os.path

import numpy as np
import pandas as pd

from iri import RQI
from pbix import PBI
from pci import PCI
from rdi import RDI
from collections import Counter

from sfc import SRI


class PQI(object):
    def __init__(self, L=52, T=5, B=0, N=1, save_dir='outputs'):
        '''
        @param
        N: 养护路段长度(向上取整)
        T: 养护周期
        B: 养护路段交通量
        L: 养护路段车道数
        '''

        # 保存日志
        self.save_dir = save_dir
        if not os.path.exists(self.save_dir):
            os.makedirs(self.save_dir)

        self.LANES = 1  # 车道总数
        self.L = L  # 维护线路总长度
        self.T = T  # 维护周期(单位: 年)
        self.B = B  # 养护路段交通量
        self.N = N  # 养护路段车道数

        self.rdi = RDI(L, self.save_dir)
        self.rqi = RQI(L)
        self.sri = SRI(L)

        self.C = np.array([0, 18.7, 53, 82, 80, 168, 280, 520]).reshape(-1, 1)  # 养护措施j的单价
        self.E = np.array([0, 0.23, 0.8, 0.92, 1.44, 1.54, 1.60, 1.64]).reshape(-1, 1)  # 养护措施j的碳排放
        self.Li = 1.0  # 默认单位路段长度(Km)
        self.Wi = 3.4090 * self.LANES  # 论文中计算得到单个车道宽度3.4090m


    def F1(self, j):
        Wpci = 0.35
        Wrqi = 0.30
        Wrdi = 0.15
        Wpbi = 0.10
        Wsri = 0.10
        Wpwi = 0.0
        Wpssi = 0.0
        res = []
        pqis = []
        for t in range(self.T):
            rd = self.rdi.rd_new(t, j, self.B)
            iri = self.rqi.iri_new(t, j, self.B)
            sfc = self.sri.sfc_new(t, j, self.B)
            i = self.rdi.calc_maintenance_type(t, j, self.B)

            pqi = Wpci * PCI() + Wrqi * self.rqi.RQI(iri) + Wrdi * self.rdi.RDI(
                rd) + Wpbi * PBI() + Wsri * self.sri.SRI(sfc)
            pqis.append(pqi)
            res.append(np.sum(self.Li / self.L * pqi, axis=1))
        pd.DataFrame(np.array(pqis).reshape(-1, self.L)).to_csv('outputs/all-pqis.csv')
        res = np.mean(np.array(res), axis=0, keepdims=True).reshape(-1, 1)
        return res

    def F2(self, j):
        Lim = self.Li * 1000  # 默认单位路段长度(单位: m)
        fee = []
        for t in range(self.T):
            i = self.rdi.calc_maintenance_type(t, j, self.B)
            cost = np.sum(self.C[i] * Lim * self.Wi, axis=1).squeeze()
            fee.append(cost)
        pd.DataFrame(np.array(fee)).to_csv('{}/fees.csv'.format(self.save_dir))
        fee = np.sum(np.array(fee), axis=0, keepdims=True).reshape(-1, 1)
        return fee / 10000.  # (万元)

    def F3(self, j):
        Lim = self.Li * 1000  # 默认单位路段长度(单位: m)
        carbon = []
        for t in range(self.T):
            i = self.rdi.calc_maintenance_type(t, j, self.B)
            c = np.sum(self.E[i] * Lim * self.Wi, axis=1).squeeze()
            carbon.append(c)
        pd.DataFrame(np.array(carbon)).to_csv('{}/carbon.csv'.format(self.save_dir))
        carbon = np.sum(np.array(carbon), axis=0, keepdims=True).reshape(-1, 1)

        return carbon / 1000.  # (吨)

    def F2_result(self, rds, j):
        Lim = self.Li * 1000  # 默认单位路段长度(单位: m)
        fee = []
        mtypes = []  # 统计后的每年维护类型
        mytypes = []  # 每年维护类型
        self.rdi.update_rds(rds)  # 更新RD
        for t in range(self.T):
            i = self.rdi.calc_result_maintenance_type(t, j, self.B)
            mytypes.append(i)
            d = dict(Counter(i))
            mtypes.append(dict(sorted(d.items(), key=lambda d1: d1[0])))
            cost = np.sum(self.C[i] * Lim * self.Wi, axis=1).squeeze()
            fee.append(cost)

        pd.DataFrame(mytypes).to_csv('{}/每年养护类别.csv'.format(self.save_dir))
        pd.DataFrame(mtypes).to_csv('{}/统计养护类别.csv'.format(self.save_dir))
        pd.DataFrame(np.array(fee) / 10000.).to_csv('{}/fees-result.csv'.format(self.save_dir))
        fee = np.sum(np.array(fee), axis=0, keepdims=True).reshape(-1, 1)
        print('Total Fee: {}'.format(np.sum(fee)))
        return np.sum(fee) / 10000.  # (万元)

    def F3_result(self, rds, j):
        Lim = self.Li * 1000  # 默认单位路段长度(单位: m)
        carbon = []
        self.rdi.update_rds(rds)
        for t in range(self.T):
            i = self.rdi.calc_result_maintenance_type(t, j, self.B)
            c = np.sum(self.E[i] * Lim * self.Wi, axis=1).squeeze()
            carbon.append(c)
            # np.delete(j)

        pd.DataFrame(np.array(carbon) / 1000.).to_csv('{}/carbons-result.csv'.format(self.save_dir))
        carbon = np.sum(np.array(carbon), axis=0, keepdims=True).reshape(-1, 1)
        # print('carbon: {}'.format(carbon))
        print('Total Fee: {}'.format(np.sum(carbon)))
        return np.sum(carbon) / 1000.  # (吨)

    def calc_result(self, j, maintainDept, roadNo, startingStation, year, duration):
        rds = np.array(pd.read_csv('{}/养护指标.csv'.format(self.save_dir), usecols=['rd']))
        mtype = []
        self.rdi.update_rds(rds)
        for t in range(self.T):
            i = self.rdi.calc_result_maintenance_type(t, j, self.B)
            # c = np.sum(self.E[i] * Lim * self.Wi, axis=1).squeeze()
            mtype.append(i)
            # np.delete(j)

        # csv_file = '{}/carbons-result.csv'.format(self.save_dir)
        csv_file = 'outputs/{}_{}_{}({}-{}).csv'.format(maintainDept, roadNo, startingStation, year, year + duration)
        pd.DataFrame(np.array(mtype)).to_csv(csv_file)
        return csv_file
        # carbon = np.sum(np.array(carbon), axis=0, keepdims=True).reshape(-1, 1)
        # # print('carbon: {}'.format(carbon))
        # print('Total Fee: {}'.format(np.sum(carbon)))
        # return np.sum(carbon) / 1000.  # (吨)


if __name__ == '__main__':
    pqi = PQI()

    # j: 养护类别
    # b: 路段交通量
    var = np.array(
        [[0, 5, 5, 7, 3, 3, 3, 3, 7, 3, 3, 5, 7, 7, 7, 5, 7, 3, 7, 5, 3, 5, 5, 7, 3, 7, 6, 3, 7, 7, 7, 7, 4, 6, 7, 3, 7,
          5, 7, 7, 7, 7, 3, 5, 6, 5, 7, 6, 7, 7, 5, 5, 3]]).reshape(1, -1)
    b = var[:, 0]
    js = var[:, 1:]

    # F2(2, 1)
    # MT = calc_maintenance_type(3)
    # print(MT)
    pqi.F1(js)
    # rd = RD(0)
    # print(rd)
    #
    # rdi = RDI(rd)
    # print(rdi)
